/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * This file is part of Harmattan SmashMiner OpenGL game application.
 * 
 * Harmattan SmashMiner OpenGL Example Application version 1.0.0
 *  
 * Latest update: 15.4.2011
 *
 * The Harmattan SmashMiner OpenGL example application demonstrates how to use 
 * the OpenGL ES in Harmattan devices.
 *
 * This example is provided as a starting point for 3rd party
 * developers (you) to ease the implementation of OpenGL based 
 * games. Ideas, parts of code or methodologies that this
 * example application uses can be freely used without restrictions.
 *
 * See file README.txt how to build and compile this example application
 * in the Harmattan SDK environment. 
 * 
 * See file INSTALL.txt to find out what is required to run this
 * application and how to install the application to the device or
 * alternatively in QEMU-emulator.
 *
 * The LICENSE.txt file explains the license this software is provided
 * with. A copy of the same license is included in this source file.
 * 
 */

/*
 * Copyright (C) 2011 by Nokia Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/// \file soundengine.h

#ifndef SOUNDENGINE_H
#define SOUNDENGINE_H

#include <QObject>
#include <QAudioOutput>
#include "defines.h"


/*!
    \enum ::SoundEffectType

    \brief Type of sound effect played by the SoundEngine.

    \sa SoundEngine
*/
enum SoundEffectType {
        /// No sound played
        SoundNull = -1,
        /// Menu sound
        SoundMenu = 0,
        /// Collision sound
        SoundCollision = 1,
        /// Explosion sound
        SoundExplosion = 2,
        /// Blast sound
        SoundBlast = 3,
        /// High score sound
        SoundHighScore = 4,
        /// Game over sound
        SoundGameOver = 5,
        /// Collect collectible item sound
        SoundCollect= 6,
        /// Number of sound effects. NOTE! This must always be the last.
        NumberOfSounds
};

class SoundEffect;
class QFile;
class WavFile;

#ifdef SMASHMINER_CONFIG_ENABLE_SOUND_ENGINE_QAUDIO
class SoundEngineQAudio;
#endif

#ifdef SMASHMINER_CONFIG_ENABLE_SOUND_ENGINE_PULSE_AUDIO
class SoundEnginePulseAudio;
#endif

class SoundEngine : public QObject
{
    Q_OBJECT

public:

    explicit SoundEngine(int volumeLevel, QObject *parent = 0);

    ~SoundEngine();

    SoundEffect *createSoundEffect(SoundEffectType, int frame, FPtype timeStamp);

public slots:
    void setVolumeLevel(int volumeLevel);
    void play(SoundEffectType);
    Q_INVOKABLE void playMenuSound();

private:
    void loadFile(SoundEffectType effectType, const QString &fileName);

    QByteArray* initialize(QFile &file, WavFile &wavFile, SoundEffectType effectType);

    void addEffectBuffer(SoundEffectType effectType, QByteArray *buffer) {Q_UNUSED(effectType); Q_UNUSED(buffer);};

    void setSoundLength(SoundEffectType effectType, qint64 length) {Q_UNUSED(effectType); Q_UNUSED(length);};

    void setAudioFormat(const QAudioFormat &audioFormat) {Q_UNUSED(audioFormat);};

    QAudioOutput* audioOutput() {return NULL;};

    void setAudioOutput(QAudioOutput *audioOutput) {Q_UNUSED(audioOutput);};

    QString formatToString(const QAudioFormat &format);

    static qint64 audioDuration(const QAudioFormat &, qint64);
    static qint64 audioLength(const QAudioFormat &, qint64 );

    // Check whether the audio format is PCM
    static bool isPCM(const QAudioFormat &);
    // Check whether the audio format is signed, little-endian, 16-bit PCM
    static bool isPCMS16LE(const QAudioFormat &);

private:

#if defined SMASHMINER_CONFIG_ENABLE_SOUND_ENGINE_QAUDIO
    SoundEngineQAudio *soundEngine;
#elif defined SMASHMINER_CONFIG_ENABLE_SOUND_ENGINE_PULSE_AUDIO
    /// Instance of sound engine used at playback
    SoundEnginePulseAudio *soundEngine;
#else
    SoundEngine *soundEngine; /// SoundEngine instance to be used to play game sound effects.
#endif
};

#endif // SOUNDENGINE_H
